package com.zhiyou100.util.object;

import cn.hutool.core.util.ReflectUtil;
import lombok.SneakyThrows;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Object 工具类
 *
 * @author yang yang yang yang
 * @version 1.0.0
 * @date 2020-08-29 11:48
 */
public class ObjectUtil {
    /**
     * 获取一个对象 为 null 的字段，把字段名放入 list 中
     *
     * @param object 对象
     * @return 为 null 字段名字的列表
     */
    @SneakyThrows
    public static List<String> getNullFiled(Object object) {
        // 创建对象，记录该对象为 null 的字段名字
        final ArrayList<String> list = new ArrayList<>();
        // 获取 class 文件
        final Class<?> aClass = object.getClass();

        for (Field field : ReflectUtil.getFields(aClass)) {
            // 暴力访问
            field.setAccessible(true);
            // 获取字段对应的值
            final Object fieldValue = field.get(object);
            if (fieldValue == null) {
                // 为 null，放入 list
                list.add(field.getName());
            }
        }
        return list;
    }

    /**
     * 只有一个字段为 null，并且是 id
     *
     * @param object 对象
     * @param id     id
     * @return true|false
     */
    public static boolean onlyOneFiledIsNullAndTheFiledIsId(Object object, String id) {
        final List<String> nullFiled = getNullFiled(object);
        return nullFiled.size() == 1 && nullFiled.contains(id);
    }

    /**
     * 有多个字段为 null，并且和传入的 id 对应
     *
     * @param object 对象
     * @param id     id
     * @return 如果数量一致，且一一对应，返回 true，否则返回 false
     */
    public static boolean onlyOneFiledIsNullAndTheFiledIsId(Object object, String... id) {
        final List<String> nullFiled = getNullFiled(object);
        // 对象中为 null 的数量和传入的字段一致
        boolean flag1 = nullFiled.size() == id.length;
        boolean flag2 = true;
        for (String s : id) {
            if (!nullFiled.contains(s)) {
                // 如果不包含其中一个字段，返回 false
                flag2 = false;
                break;
            }
        }
        return flag1 && flag2;
    }
}
